﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.Net;
using System.Xml.Linq;
using System.Web;

namespace ProductionMonitor
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            this.button1.IsEnabled = false;
            Thread thread = new Thread(DoMonitor);
            thread.IsBackground = true;
            thread.Start();
        }

        private void DoMonitor()
        {
            while (true)
            {
                CheckContext checkContext;
                try
                {
                    while (true)
                    {
                        try
                        {
                            checkContext = InitialStep();
                            break;
                        }
                        catch (Exception ex)
                        {
                        }
                    }

                    while (true)
                    {
                        try
                        {
                            string productionInfo = SelectStoreStep(checkContext);
                            if (productionInfo != null)
                            {
                                this.Dispatcher.BeginInvoke(new Action(() => { this.Activate(); MessageBox.Show("Production Available!!!\r\n" + productionInfo); }));
                                return;
                            }
                            Thread.Sleep(5000);
                        }
                        catch (Exception ex)
                        {
                            if (ex is TimeoutException)
                            {
                                throw;
                            }
                        }
                    }
                }
                catch (Exception ex)
                { 
                    
                }
            }
        }

        private CheckContext InitialStep()
        {
            RequestContext context = new RequestContext();
            context.RequestUrl = "http://reserve.apple.com/WebObjects/ProductReservation.woa/wa/reserveProduct?lang=en&country=HK&prelaunch=MC637ZP/A";
            context.AllowAutoRedirect = false;
            context.Method = "GET";
            context.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            context.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
            context.Headers.Add("Accept-Language", "en-US,en;q=0.8");
            context.Headers.Add("Cookie", "0");

            ResponseContext response = Helper.GetResponse(context);
            if (response.StatusCode != HttpStatusCode.OK)
            {
                throw new Exception();
            }
            if (response.Content.Contains("id=\"isCartEmpty\"") == false)
            {
                throw new TimeoutException();
            }

            string cookieString = response.Headers.Get("set-cookie");
            int index;
            index = cookieString.IndexOf("NSC_");
            string nscCookieName = cookieString.Substring(index, cookieString.IndexOf('=', index) - index);
            string cookie = Helper.GetCookie(cookieString, new List<string>() { "RPRCookie", "wosid", "woinst", nscCookieName });

            string responseContent = response.Content;

            List<string> postDataIds = new List<string>() { "id=\"isCartEmpty\"", "id=\"productImage\"", "id=\"defaultStoreImage\"" };
            string selectStorePostData = string.Empty;
            int beginIndex;
            string domHTML;
            XDocument dom;
            foreach (var item in postDataIds)
            {
                index = responseContent.IndexOf(item);
                while (responseContent[index] != '<')
                {
                    index--;
                }

                beginIndex = index;

                while (responseContent[index] != '>')
                {
                    index++;
                }

                domHTML = responseContent.Substring(beginIndex, index - beginIndex + 1);
                dom = XDocument.Parse(domHTML);
                selectStorePostData = selectStorePostData + dom.Root.Attribute("name").Value + "=" + HttpUtility.UrlEncode(dom.Root.Attribute("value").Value) + "&";
            }
            selectStorePostData = selectStorePostData + "storeNumber=R428";

            index = responseContent.IndexOf("id=\"TheForm\"");
            while (responseContent[index] != '<')
            {
                index--;
            }

            beginIndex = index;

            while (responseContent[index] != '>')
            {
                index++;
            }

            domHTML = responseContent.Substring(beginIndex, index - beginIndex) + "/>";
            dom = XDocument.Parse(domHTML);
            string selectStoreAction = "http://reserve.apple.com" + dom.Root.Attribute("action").Value;

            return new CheckContext(cookie, selectStoreAction, selectStorePostData); 
        }

        private string SelectStoreStep(CheckContext checkContext)
        {
            RequestContext context = new RequestContext();
            context.RequestUrl = checkContext.Url;
            context.AllowAutoRedirect = false;
            context.Method = "POST";
            context.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            context.ContentType = "application/x-www-form-urlencoded";
            context.PostData = checkContext.PostData;
            context.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
            context.Headers.Add("Accept-Language", "en-US,en;q=0.8");
            context.Headers.Add("Cookie", checkContext.Cookie);

            ResponseContext response = Helper.GetResponse(context);
            if (response.StatusCode != HttpStatusCode.OK)
            {
                throw new Exception();
            }
            bool isTimeout = Helper.CheckSessionTimeout(checkContext.Cookie, response.Headers.Get("set-cookie"));
            if (isTimeout == true)
            {
                throw new TimeoutException();
            }

            string productionInfo = null;

            if (response.Content.Contains("MD235Z") == true)
            {
                productionInfo += "B 16G | ";
            }

            if (response.Content.Contains("MD242Z") == true)
            {
                productionInfo += "B 32G | ";
            }

            if (response.Content.Contains("MD258Z") == true)
            {
                productionInfo += "B 64G | ";
            }

            return productionInfo;
        }
    }

    public class CheckContext
    {
        public CheckContext(string cookie, string url, string postData)
        {
            Cookie = cookie;
            Url = url;
            PostData = postData;
        }

        public string Cookie { get; private set; }
        public string Url { get; private set; }
        public string PostData { get; private set; }
    }
}
